package view.content;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import java.util.logging.Level;

import javax.imageio.ImageIO;

import model.ImageStore;
import model.Player;
import model.PlaylistRecord;
import model.Preference;
import model.Settings;
import model.contents.Content;
import model.contents.ContentType;
import net.HttpRequestFacade;
import util.CMYKtowebtool;
import util.EmailSending;
import util.ExceptionTracker;
import util.LoggingUtils;
import view.ProportionalAreaFitter;

public class ImageBox extends ContentBox implements ProportionalAreaFitter {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static ImageStore store;
	//protected final String className = this.getClass().getName();
	private BufferedImage image;

	static {
		store = new ImageStore();
		loadImages();
	}

	public static void resetImageStore() {
		store = new ImageStore();
	}

	public static void loadImages() {
		List<PlaylistRecord> records = Player.getInstance().getRecords();
		for (PlaylistRecord record : records) {
			Content content = record.getContent();
			if (content == null || content.getType() != ContentType.IMAGE) {
				continue;
			} else {
				String imagePath = content.getLocalPath();
				try {
					File imageFile = new File(content.getLocalPath());
					//if(imageFile.exists()) {
					if(!store.hasImage(imagePath) && imageFile.exists()) {	
						store.putImage(imagePath, ImageIO.read(imageFile));
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
					final String classMethod = "view.content.ImageBox .loadImages()";
					LoggingUtils.logStart(classMethod);
					LoggingUtils.log(Level.SEVERE,classMethod+"\nImage Name: = "+imagePath+"\n",e);
					final String imageLoc = imagePath;

					final String exceptionmessage = EmailSending.FormatException(e);

					if(!ExceptionTracker.isExceptionNotifiedByKey(content.getLocalPath()))
					{
						ExceptionTracker.setExceptionInTracker(content.getLocalPath(),e.getMessage());
						Thread emailingThread = new Thread(new Runnable() {
							@Override
							public void run() {

								String EmailBody = EmailSending.ProcessEmailBody(imageLoc+" exception has formating problem "+classMethod, 
										"general error:Notification, Image not playing", exceptionmessage);

								util.EmailSending.getInstance().send(Settings.TO_USER, "Image error:Notification" +
										"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
							}
						});

						emailingThread.setName("Emailing");
						emailingThread.start();
					}

					final String imagename = content.getPath();
					final int imageid	= content.getId();

					Thread notificationThread = new Thread(new Runnable() {

						@Override
						public void run() {
							HttpRequestFacade.PostToConvertImage(imageid);
						}
					});
					notificationThread.setName("Invalid Image Format Notification Thread");
					notificationThread.start();

					CMYKtowebtool.getInstance().setValue(imagename, String.valueOf(content.getId()));


					content.delete();
				}
				catch (Error e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
					final String classMethod = "view.content.ImageBox .loadImages()";
					LoggingUtils.logStart(classMethod);
					LoggingUtils.log(Level.SEVERE,classMethod+"\nImage Name: = "+imagePath+"\n",e);
				}
			}
		}
	}


	public ImageBox(Content content, int width, int height) {
		super(content, width, height);
		this.initialize(this.width, this.height);
	}

	private void initialize(int width, int height) {
		this.width = width;
		this.height = height;
		this.setDoubleBuffered(true);
		this.setOpaque(false);
		this.setLayout(new BorderLayout());
		this.setPreferredSize(new Dimension(width, height));

		BufferedImage bi = null;
		try {
			bi = this.loadImage();
			if (bi != null) {
				this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
				Graphics g2 = this.image.getGraphics();
				g2.drawImage(bi, 0, 0, width, height, null, null);
				g2.dispose();
			}

		} catch (Exception ex) {
			ex.printStackTrace();

			String classMethod = "view.content.ImageBox .initialize(int width, int height)";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,ex.getMessage(),ex);
		}
	}

	@Override
	public void paintComponent(Graphics g) {
		if (this.image != null) {
			// System.out.println("painting component.");
			// g2d.setColor(PlayerUtilities.getRandomColor());
			// g2d.fillRect(0, 0, this.width, this.height);
			g.drawImage(this.image, 0, 0, null);
		}
	}

	private BufferedImage loadImage() {
		BufferedImage bi = null;
		File imageFile = new File(content.getLocalPath());

		if (!imageFile.exists()) {
			return null;
		}
		try {
			if(store.hasImage(content.getLocalPath())) {
				bi = store.getImage(content.getLocalPath());
			} else {
				bi = ImageIO.read(imageFile);
			}
			return bi;
		} catch (Exception e) {
			e.printStackTrace();

			final String classMethod = "view.content.ImageBox private .BufferedImage loadImage()";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,e.getMessage() + "Cannot read input file",e);

			System.out.println("Cannot read input file " + content.getLocalPath());
			final String exceptionmessage = EmailSending.FormatException(e);

			if(!ExceptionTracker.isExceptionNotifiedByKey(content.getLocalPath()))
			{
				ExceptionTracker.setExceptionInTracker(content.getLocalPath(),e.getMessage());

				Thread emailingThread = new Thread(new Runnable() {
					@Override
					public void run() {
						String EmailBody = EmailSending.ProcessEmailBody(content.getLocalhtmlPath()+" has formating problem exception "+classMethod, 
								"general error:Notification, Image not playing", exceptionmessage);

						util.EmailSending.getInstance().send(Settings.TO_USER, "Image error:Notification" +
								"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
					}
				});
				emailingThread.setName("Emailing Thread");
				emailingThread.start();
			}

			/* Sending to convert image request to webtool */

			Thread notificationThread = new Thread(new Runnable() {

				@Override
				public void run() {
					HttpRequestFacade.PostToConvertImage(ImageBox.this.getContent().getId());
				}
			});
			notificationThread.setName("Invalid Image Format Notification Thread");
			notificationThread.start();

			CMYKtowebtool.getInstance().setValue(ImageBox.this.getContent().getPath(), String.valueOf(ImageBox.this.getContent().getId()));

			ImageBox.this.content.delete();
		}
		catch(Error e)
		{
			final String classMethod = "view.content.ImageBox .BufferedImage private loadImage()";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,e.getMessage() + "Cannot read input file",e);
		}
		return bi;
	}

	@Override
	public void fit(int maxWidth, int maxHeight) {
		BufferedImage image = this.loadImage();
		if (image == null) {
			return;
		}
		double scale = calculateFittingScale(maxWidth, maxHeight, image.getWidth(), image.getHeight());
		int width = (int) (image.getWidth() * scale);
		int height = (int) (image.getHeight() * scale);
		this.initialize(width, height);
		this.revalidate();
		this.repaint();
	}

	private double calculateFittingScale(int maxWidth, int maxHeight, int imageWidth, int imageHeight) {
		double widthRatio = (double) imageWidth / maxWidth;
		double heightRatio = (double) imageHeight / maxHeight;
		double scale = 1 / Math.max(widthRatio, heightRatio);
		return scale;
	}

}